package com.yaodian100.ec.timelimitsale.service.impl;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;

import com.yaodian100.core.admin.entity.Role;
import com.yaodian100.core.admin.entity.User;
import com.yaodian100.core.admin.entity.UserPermission;
import com.yaodian100.core.admin.entity.Permission.Type;
import com.yaodian100.core.admin.service.UserService;
import com.yaodian100.core.admin.utils.AdminHelper;
import com.yaodian100.core.common.dao.ObjectDao;
import com.yaodian100.core.common.dao.impl.CommonCriteria;
import com.yaodian100.core.common.dao.impl.CriteriaInRlike;
import com.yaodian100.core.common.exception.CoreException;
import com.yaodian100.core.common.service.impl.DomainServiceImpl;
import com.yaodian100.core.common.utils.ServerValue;
import com.yaodian100.core.mail.entity.Mail;
import com.yaodian100.core.mail.service.MailService;
import com.yaodian100.core.template.service.TemplateService;
import com.yaodian100.ec.generate.entity.EventImage;
import com.yaodian100.ec.member.service.MemberService;
import com.yaodian100.ec.product.entity.Product;
import com.yaodian100.ec.product.entity.Specification;
import com.yaodian100.ec.product.entity.SpecificationInventory;
import com.yaodian100.ec.product.service.ProductService;
import com.yaodian100.ec.shelf.entity.Shelf;
import com.yaodian100.ec.shelf.entity.ShelfTuangou;
import com.yaodian100.ec.shelf.service.ShelfService;
import com.yaodian100.ec.shopping.entity.CartOrderProduct;
import com.yaodian100.ec.timelimitsale.entity.TimeLimitMain;
import com.yaodian100.ec.timelimitsale.entity.TimeLimitNow;
import com.yaodian100.ec.timelimitsale.entity.TimeLimitProd;
import com.yaodian100.ec.timelimitsale.service.TimeLimitSaleService;

public class TimeLimitSaleServiceImpl extends DomainServiceImpl<TimeLimitMain> implements TimeLimitSaleService {

	private static final String TIMESALE_CONTACT = "TIMESALE_CONTACT";
	private ObjectDao<TimeLimitNow> timeLimitNowDao;
	private ObjectDao<TimeLimitProd> timeLimitProdDao;
	private ObjectDao<EventImage> eventImageDao;
	@Resource
	private JdbcTemplate jdbcTemplate;

	@Autowired
	private ProductService productService;
	@Autowired
	private MemberService memberService;
	@Autowired
	private TemplateService templateService;
	private UserService userService;
	@Autowired
	private MailService mailService;
	@Autowired
	private ShelfService shelfService;
	private final String STRING_SYMBOL = "/";

	@Override
	public boolean isTimeLimitSale(String productId) {
		CommonCriteria criteria = new CommonCriteria();
		criteria.addEq("productId", productId);
		List<TimeLimitNow> tln = getTimeLimitNowDao().getList(criteria, null);
		if (null == tln) {
			return false;
		}
		return tln.size() > 0;
	}

	/**
	 * for 进购物车 & 购物车-結帳
	 */
	@Override
	public String canBuy(List<CartOrderProduct> cartOrderProducts, String memberId) {
		if (StringUtils.isBlank(memberId)) {
			return OK;
		}
		if ("nonmember".equals(memberService.get(memberId).getApplySource())) {
			List<String> tlpListn = findTimeLimitSale(cartOrderProducts);
			if (null == tlpListn || tlpListn.isEmpty()) {
				return OK;
			} else {
				return NONMEMBER;
			}
		}
		List<String> tlpList = findTimeLimitSale2(cartOrderProducts);
		if (tlpList.isEmpty()) {
			return OK;
		}
		for (String prodId : tlpList) {
			if (findEverBuy(prodId, memberId)) {
				return EVER_BUY;
			}
		}
		return OK;
	}

	/**
	 * for 立即购买
	 */
	@Override
	public String canBuy(String productId, String memberId) {
		if ("nonmember".equals(memberService.get(memberId).getApplySource())) {
			return NONMEMBER;
		}
		if (!isTimeLimitSale(productId)) {
			return OK;
		}
		if (findEverBuy(productId, memberId)) {
			return EVER_BUY;
		}
		return OK;
	}

	@Override
	public String canAdd(String productId, String memberId, List<CartOrderProduct> cartOrderProducts) {
		List<String> tlpList = findTimeLimitSale2(cartOrderProducts);
		if ((!tlpList.isEmpty()) && tlpList.contains(productId)) {
			return MULTIPLE_PROD;
		}
		if (StringUtils.isBlank(memberId)) { // 进购物车允许未登入
			return OK;
		}
		if (memberService.get(memberId).getApplySource().equals("nonmember")) {
			return NONMEMBER;
		}
		if (findEverBuy(productId, memberId)) {
			return EVER_BUY;
		}
		return OK;
	}

	@SuppressWarnings("unchecked")
	private boolean findEverBuy(String productId, String memberId) {
		StringBuffer sb = new StringBuffer();
		sb.append("select n.* from ");
		sb.append("( ec_order_main o inner join ec_order_product p on o.order_id = p.order_id ) ");
		sb.append("inner join ec_time_limit_now n on p.prod_id = n.product_Id ");
		sb.append("where o.member_id = ? and n.product_Id = ? and n.IS_LIMIT_BUY = 'Y' ");
		sb.append("and o.order_dt between ");
		sb.append("n.start_date and n.end_date and o.order_st not in ('80','81','70')");
		List attr = new ArrayList();
		attr.add(0, memberId);
		attr.add(1, productId);
		List list = getDao().getSQLQueryByList(sb.toString(), attr, 0, -1);
		if (!list.isEmpty()) {
			return true;
		}
		return false;
	}

	@Override
	public List<String> findTimeLimitSale(List<CartOrderProduct> cartOrderProduct) {
		if (null == cartOrderProduct || cartOrderProduct.size() == 0) {
			return null;
		}
		ArrayList<String> prodId = new ArrayList<String>();
		for (CartOrderProduct cop : cartOrderProduct) {
			prodId.add(cop.getProdId());
		}
		CommonCriteria criteria = new CommonCriteria();
		criteria.addIn("productId", prodId);
		List<TimeLimitNow> tlns = getTimeLimitNowDao().getList(criteria, null);
		if (null == tlns || tlns.size() == 0) {
			return null;
		}
		List<String> tlsProduct = new ArrayList<String>();
		for (TimeLimitNow tln : tlns) {
			tlsProduct.add(tln.getProductId());
		}
		return tlsProduct;
	}

	private List<String> findTimeLimitSale2(List<CartOrderProduct> cartOrderProduct) {
		List<String> tlsProduct = new ArrayList<String>();
		if (null == cartOrderProduct || cartOrderProduct.size() == 0) {
			return tlsProduct;
		}
		ArrayList<String> prodId = new ArrayList<String>();
		for (CartOrderProduct cop : cartOrderProduct) {
			prodId.add(cop.getProdId());
		}
		CommonCriteria criteria = new CommonCriteria();
		criteria.addEq("isLimitBuy", "Y");
		criteria.addIn("productId", prodId);
		List<TimeLimitNow> tln = getTimeLimitNowDao().getList(criteria, null);
		if (null == tln) {
			return tlsProduct;
		}
		for (int i = 0; i < tln.size(); i++) {
			tlsProduct.add(tln.get(i).getProductId());
		}
		return tlsProduct;
	}

	@Override
	@Transactional(readOnly = false)
	public boolean saveTimeLimitSale(TimeLimitMain tlm, List<TimeLimitProd> tlpList) {
		if (null == tlm.getId()) {
			tlm = save(tlm);
		} else {
			tlm = update(tlm);
		}
		for (TimeLimitProd tlp : tlpList) {
			tlp.setMainId(tlm.getId());
			tlp = saveOrUpdateTimeLimitProd(tlp);
		}
		return true;
	}

	@Override
	@Transactional(readOnly = false)
	public boolean updateData(String date) throws ParseException, CoreException, IOException {
		DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
		Date time = df.parse(date);
		undateNow(time); // update TimeLimitSaleNow
		return true;
	}

	/**
	 * 更新目前限抢商品
	 * 
	 * @param date
	 * @throws ParseException
	 * @throws IOException
	 * @throws CoreException
	 */
	private void undateNow(Date date) throws ParseException, CoreException, IOException {
		List<String> allSaleNow = new ArrayList<String>();

		// clear
		jdbcTemplate.execute("truncate table EC_TIME_LIMIT_NOW drop storage ");

		// update & save & generate tln
		if (!generateDate(date, allSaleNow)) {
			generateIdxEmpty();
		}

		// update today all product
		DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
		if (df.format(date).substring(8, 10).equals("00")) {
			String tmp = df.format(date).substring(0, 8);
			CommonCriteria criteria = new CommonCriteria();
			criteria.addGe("startDate", df.parse(tmp + "010000"));
			criteria.addLe("startDate", df.parse(tmp + "235959"));
			criteria.addNe("imagePath", "img_path");
			List<TimeLimitProd> tlpList = getTimeLimitProdDao().getList(criteria, null);
			if (null != tlpList) {
				for (TimeLimitProd tlp : tlpList) {
					if (!allSaleNow.contains(tlp.getProductId())) {
						Product p = productService.get(tlp.getProductId());
						if (null == p) {
							continue;
						}
						p.setIsDelete("Q");
						if (p.getProductType() != 6 && tlp.getIsLimitBuy().equals("Y")) {
							criteria = new CommonCriteria();
							criteria.addEq("productId", tlp.getProductId());
							List<Specification> specList = productService.getSpecificationList(0, -1, criteria, null);
							if (null != specList && (!specList.isEmpty())) {
								for (Specification spec : specList) {
									spec.setMaxCountPerOrder(1);
									productService.saveSpecification(spec);
								}
							}
						}
						productService.updateNoSync(p);
					}
				}
			}
		}

	}

	@Override
	@Transactional(readOnly = false)
	public boolean generateTimeLimitSaleList(String date, int categoryId) throws ParseException, CoreException,
			IOException {
		String checkShelf = null;
		DateFormat df = new SimpleDateFormat("yyyyMMdd");
		DateFormat df2 = new SimpleDateFormat("yyyyMMddHHmmss");
		Date time = df.parse(StringUtils.substring(date, 0, 8));
		Date genTime = df2.parse(date);
		CommonCriteria criteria = new CommonCriteria();
		criteria.addEq("saleDate", time);
		criteria.addEq("categoryID", categoryId);
		List<TimeLimitMain> tlmList = getList(0, -1, criteria, null);
		if (null == tlmList || tlmList.isEmpty()) {
			return true;
		}

		criteria = new CommonCriteria();
		criteria.addEq("mainId", tlmList.get(0).getId());
		List<TimeLimitProd> tlpList = getTimeLimitProdDao().getList(criteria, new String[] { "startDate asc" });
		if (null == tlpList || tlpList.isEmpty()) {
			return true;
		}

		// 检查库存 & 结束时间
		Map<String, String> qtyMap = new HashMap<String, String>();
		List<String> remindProd = new ArrayList<String>();
		List<String> errProd = new ArrayList<String>();
		StringBuffer plistSb = new StringBuffer();
		for (int i = 0; i < tlpList.size(); i++) {
			TimeLimitProd tlp = tlpList.get(i);
			tlp.setTmpEndDate(tlp.getEndDate());
			if ((i < tlpList.size() - 1) && tlpList.get(i + 1).getIsRepeat().equals("Y")) {
				i++;
				for (int j = i; j < tlpList.size(); j++) {
					if (tlpList.get(j).getIsRepeat().equals("Y")) {
						tlp.setTmpEndDate(tlpList.get(j).getEndDate());
					} else {
						i = j - 1;
						break;
					}
				}
			}
			if (tlp.getIsRepeat().equals("N")) {
				// 发信资讯, 先全部加入
				if (tlp.getStartDate().getTime() > genTime.getTime()) {
					remindProd.add(tlp.getProductId());
				}
				if (plistSb.toString().indexOf(tlp.getProductId()) == -1) {
					if (plistSb.length() != 0) {
						plistSb.append(", ");
					}
					plistSb.append("'").append(tlp.getProductId()).append("'");
				}

				// 抢购中商品
				if (tlp.getStartDate().getTime() <= genTime.getTime() && tlp.getTmpEndDate().getTime() > genTime.getTime()) {
					List<Map<String, Object>> shelfList = jdbcTemplate
							.queryForList("select * from ec_view_shelf where product_id = '" + tlp.getProductId() + "' ");
					Shelf s = shelfService.getActiveShelfByProductId(tlp.getProductId());
					if (null == shelfList || shelfList.isEmpty()) {
						checkShelf = "秒杀中商品:" + tlp.getProductId() + " 未上架";
					} else if (new BigDecimal(shelfList.get(0).get("SHELF_PRICE").toString()).compareTo(tlp.getLimitPrice()) != 0) {
						checkShelf = "秒杀中商品:" + tlp.getProductId() + " 秒杀价:" + tlp.getLimitPrice() + " 卖场价格:" + s.getShelfPrice();
					}
				}
			}
		}
		plistSb.insert(0, "From Ec_Specification_Inventory Where Product_Id In( ");
		plistSb.insert(0, "Select Product_Id, Sum(Available_Inventory - Sold_Inventory + Cancel_Inventory) Qty ");
		plistSb.insert(0, "Select Product_Id From( ");
		plistSb.append(" ) GROUP BY Product_Id) where QTY = 0 ");
		List<Map<String, Object>> pQtyList = jdbcTemplate.queryForList(plistSb.toString());
		for (Map<String, Object> pqty : pQtyList) {
			if (remindProd.contains(pqty.get("PRODUCT_ID").toString())) {
				errProd.add(pqty.get("PRODUCT_ID").toString());
			}
			qtyMap.put(pqty.get("PRODUCT_ID").toString(), "0");
		}

		if (StringUtils.isNotBlank(checkShelf) || errProd.size() > 0) {
			sendMail(checkShelf, errProd);
		}
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("contentPath", ServerValue.getFrontContextPath());
		m.put("tlpList", tlpList);
		m.put("qtyMap", qtyMap);
		m.put("genTime", genTime);
		FileUtils.writeStringToFile(new File(ServerValue.getFrontContentHtmlPath() + "COMMON" + File.separator + "TLS"
				+ File.separator + date.substring(0, 8) + ".html"), templateService.format("static_TimeLimitSaleList", m));
		return true;
	}

	private boolean generateDate(Date date, List<String> allSaleNow) throws ParseException, CoreException, IOException {
		generateSK(date);
		boolean gened = false;
		DateFormat df = new SimpleDateFormat("yyyyMMdd");
		Date time = df.parse(df.format(date));
		CommonCriteria criteria = new CommonCriteria();
		criteria.addEq("saleDate", time);
		criteria.addNe("categoryID", -1);
		List<TimeLimitMain> tlmList = getList(0, -1, criteria, null);
		if (null == tlmList || tlmList.isEmpty()) {
			return false;
		}
		for (TimeLimitMain tlm : tlmList) {
			criteria = new CommonCriteria();
			criteria.addEq("mainId", tlm.getId());
			List<TimeLimitProd> tlpList = getTimeLimitProdDao().getList(criteria, new String[] { "startDate asc" });
			if (null == tlpList || tlpList.isEmpty()) {
				continue;
			}

			// 检查起迄时间
			for (int i = 0; i < tlpList.size(); i++) {
				TimeLimitProd tlp = tlpList.get(i);
				tlp.setTmpEndDate(tlp.getEndDate());
				if ((i < tlpList.size() - 1) && tlpList.get(i + 1).getIsRepeat().equals("Y")) {
					i++;
					for (int j = i; j < tlpList.size(); j++) {
						if (tlpList.get(j).getIsRepeat().equals("Y")) {
							tlp.setTmpEndDate(tlpList.get(j).getEndDate());
						} else {
							i = j - 1;
							break;
						}
					}
				}
			}

			for (TimeLimitProd tlp : tlpList) {
				if (tlp.getIsRepeat().equals("N")) {
					if (tlp.getStartDate().getTime() <= date.getTime() && tlp.getTmpEndDate().getTime() > date.getTime()) {
						allSaleNow.add(tlp.getProductId());
						TimeLimitNow tln = new TimeLimitNow();
						tln.setStartDate(tlp.getStartDate());
						tln.setEndDate(tlp.getTmpEndDate());
						tln.setIsLimitBuy(tlp.getIsLimitBuy());
						tln.setProductId(tlp.getProductId());
						getTimeLimitNowDao().save(tln);

						if (tlm.getCategoryID() != -1) {
							gened = true;
							generateIdxTimeLimitSale(tlp, tln);
						}
						// update product main
						Product p = productService.get(tlp.getProductId());
						if (null == p) {
							continue;
						}
						Shelf s = shelfService.getActiveShelfByProductId(tlp.getProductId());
						if (null == s || s.getShelfPrice().compareTo(tlp.getLimitPrice()) != 0) {
							continue;
						}
						p.setIsDelete("N");
						productService.updateNoSync(p);
					}
				}
			}
		}
		return gened;
	}

	private void generateSK(Date date) throws ParseException, CoreException, IOException {
		DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
		StringBuffer sb = new StringBuffer();
		sb.append("Insert Into Ec_Time_Limit_Now (Id, Start_Date, End_Date, Is_Limit_Buy,Product_Id) ");
		sb.append("Select Seq_Ec_Time_Limit_Now.Nextval, Start_Date, End_Date, Is_Limit_Buy ,Product_Id ");
		sb.append("From Ec_Time_Limit_Prod ");
		sb.append("Where To_Date('" + df.format(date) + "', 'yyyyMMddhh24MIss') Between Start_Date And End_Date ");
		sb.append("and IMAGE_PATH = 'img_path' ");
		jdbcTemplate.execute(sb.toString());
	}

	private void generateIdxTimeLimitSale(TimeLimitProd tlp, TimeLimitNow tln) throws CoreException, IOException {
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("contentPath", ServerValue.getFrontContextPath());
		m.put("tlp", tlp);
		m.put("tln", tln);
		m.put("tlsEndTime", tln.getEndDate().getTime() / 1000);
		FileUtils.writeStringToFile(new File(ServerValue.getFrontContentHtmlPath() + "IDX" + File.separator
				+ "IDX_TIME_LIMIT_SALE_V3.html"), templateService.format("static_IdxTimeLimitSale_V3", m));
		FileUtils.writeStringToFile(new File(ServerValue.getFrontContentHtmlPath() + "IDX" + File.separator
				+ "IDX_TIME_LIMIT_SALE_V5.html"), templateService.format("static_IdxTimeLimitSale_V5", m));
	}

	private void generateIdxEmpty() throws IOException {
		String content = "";
		FileUtils.writeStringToFile(new File(ServerValue.getFrontContentHtmlPath() + "IDX" + File.separator
				+ "IDX_TIME_LIMIT_SALE_V3.html"), content);
	}

	@Override
	public boolean generateMTimeLimitSaleList(String date) throws CoreException, IOException, ParseException {
		DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");

		Date time = df.parse(StringUtils.substring(date, 0, 8) + "000000");
		CommonCriteria criteria = new CommonCriteria();
		criteria.addEq("saleDate", time);
		List<TimeLimitMain> tlmList = getList(0, -1, criteria, null);
		if (null == tlmList || tlmList.isEmpty()) {
			return true;
		}

		criteria = new CommonCriteria();
		criteria.addEq("mainId", tlmList.get(0).getId());
		criteria.addNe("imagePath", "img_path");
		criteria.addGe("startDate", df.parse(date));
		// 查出现在之后的档次
		List<TimeLimitProd> tlpList = getTimeLimitProdDao().getList(criteria, new String[] { "startDate asc" });
		if (null == tlpList || tlpList.isEmpty()) {
			logger.info("generateMTimeLimitSaleList{}:" + date + "无秒杀档次");
			return true;
		}
		List<TimeLimitProd> ftlpList = new ArrayList<TimeLimitProd>();
		// 检查结束时间
		for (int i = 0; i < tlpList.size(); i++) {
			TimeLimitProd tlp = tlpList.get(i);
			if (i == 0) {
				ftlpList.add(tlp);
			} else {
				TimeLimitProd tmp = ftlpList.get(ftlpList.size() - 1);
				if (tlp.getProductId().equals(tmp.getProductId())) {
					tmp.setEndDate(tlp.getEndDate());
				} else {
					ftlpList.add(tlp);
				}
			}
			if (ftlpList.size() == 5) {
				break;
			}
		}
		TimeLimitProd now = ftlpList.get(0);
		ftlpList.remove(0);
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("contentPath", ServerValue.getFrontContextPath());
		m.put("now", now);
		m.put("ftlpList", ftlpList);
		FileUtils.writeStringToFile(new File(ServerValue.getFrontContentHtmlPath() + "COMMON" + File.separator
				+ "M_TLS.html"), templateService.format("static_M_TimeLimitSaleList", m));
		return true;
	}

	@Override
	@Transactional(readOnly = false)
	public boolean sendTimeLimitSaleStatusList(String date, int categoryId) throws ParseException {
		DateFormat df = new SimpleDateFormat("yyyyMMdd");
		DateFormat df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date time = DateUtils.addDays(df.parse(StringUtils.substring(date, 0, 8)), 1);
		CommonCriteria criteria = new CommonCriteria();
		criteria.addEq("saleDate", time);
		criteria.addEq("categoryID", categoryId);
		List<TimeLimitMain> tlmList = getList(0, -1, criteria, null);
		if (null == tlmList || tlmList.isEmpty()) {
			sendMail(new Mail(df.format(time) + "限时秒杀状态列表", "无资料", null, null));
			return true; // no data
		}

		criteria = new CommonCriteria();
		criteria.addEq("mainId", tlmList.get(0).getId());
		List<TimeLimitProd> tlpList = getTimeLimitProdDao().getList(criteria, new String[] { "startDate asc" });
		if (null == tlpList || tlpList.isEmpty()) {
			sendMail(new Mail(df.format(time) + "限时秒杀状态列表", "无资料", null, null));
			return true;
		}

		// 检查库存 & 上架档
		Map<String, String> qtyMap = new HashMap<String, String>();
		Map<String, Shelf> shelfMap = new HashMap<String, Shelf>();
		for (TimeLimitProd tlp : tlpList) {
			if (tlp.getIsRepeat().equals("N") && (!qtyMap.containsKey(tlp.getProductId()))) {
				int qty = 0;
				Map<String, SpecificationInventory> smap = productService.getSpecificationInventoryMap(tlp.getProductId());
				if (!smap.isEmpty()) {
					Set<String> key = smap.keySet();
					for (Iterator<String> it = key.iterator(); it.hasNext();) {
						String name = it.next();
						SpecificationInventory sp = smap.get(name);
						qty += (sp.getAvailableInventory() - sp.getSoldInventory() + sp.getCancelInventory());
					}
					qtyMap.put(tlp.getProductId(), Integer.toString(qty));
				} else {
					qtyMap.put(tlp.getProductId(), "n選m");
				}
			}
			Shelf s = shelfService.getShelfByProductId(tlp.getProductId(), tlp.getStartDate(), DateUtils.addMinutes(tlp
					.getEndDate(), -1));
			shelfMap.put(df2.format(tlp.getStartDate()), s);
		}
		Map<String, Object> mailContentParameters = new HashMap<String, Object>();
		mailContentParameters.put("shelfMap", shelfMap);
		mailContentParameters.put("qtyMap", qtyMap);
		mailContentParameters.put("tlpList", tlpList);
		mailContentParameters.put("date", df.format(time));
		sendMail(templateService.formatToMail("timeLimitSaleStatusList", mailContentParameters));
		return true;
	}

	private void sendMail(String checkShelf, List<String> errProd) {
		// 準備郵件內容
		Map<String, Object> mailContentParameters = new HashMap<String, Object>();
		mailContentParameters.put("checkShelf", checkShelf);
		mailContentParameters.put("errProd", errProd);
		sendMail(templateService.formatToMail("timeLimitSaleWarn", mailContentParameters));
	}

	private void sendMail(Mail notification) {
		// 找出收件者
		List<User> adContactWindowList = userService.getByRole(TIMESALE_CONTACT, Role.Type.OTHER, null);
		for (User contactWindow : adContactWindowList) {
			notification.addTo(contactWindow.getNameNative(), contactWindow.getEmail());
		}
		notification.addBcc("前台组", "fe@yaodian100.com");
		mailService.save(notification);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Object> getProductList() {
		StringBuffer sb = new StringBuffer();
		sb.append("select distinct(epm.product_id), epm.product_name ");
		sb.append("From Ec_Product_Category Ecp, Ec_Product_Main Epm Where Ecp.Category_Path Like '3871/%' ");
		sb.append("and ecp.product_id = epm.product_id ");
		return getDao().getSQLQueryByList(sb.toString(), null, 0, -1);
	}

	@Override
	public TimeLimitProd getTimeLimitProd(String id) {
		return getTimeLimitProdDao().get(Long.parseLong(id));
	}

	@Override
	public List<TimeLimitProd> getTimeLimitProdList(CommonCriteria criteria) {
		CriteriaInRlike critInRlike = mergeCritInRlike(criteria, "product.category.categoryPath");// 分線維護權限檢核
		return getTimeLimitProdDao().getList(critInRlike, new String[] { "startDate asc" });
	}

	@Override
	public List<TimeLimitProd> getTimeLimitProdList(CommonCriteria criteria, String[] sortOrder, int startNode,
			int returnSize) {
		CriteriaInRlike critInRlike = mergeCritInRlike(criteria, "product.category.categoryPath");// 分線維護權限檢核
		return getTimeLimitProdDao().getListPageable(critInRlike, sortOrder, startNode, returnSize);
	}

	@Override
	public Number getTimeLimitProdListSize(CommonCriteria criteria) {
		CriteriaInRlike critInRlike = mergeCritInRlike(criteria, "product.category.categoryPath");// 分線維護權限檢核
		return getTimeLimitProdDao().getListSize(critInRlike);
	}

	@Override
	@Transactional(readOnly = false)
	public EventImage saveEventImage(EventImage eventImage) throws CoreException {
		return getEventImageDao().save(eventImage);
	}

	@Override
	@Transactional(readOnly = false)
	public TimeLimitProd saveOrUpdateTimeLimitProd(TimeLimitProd entity) {
		if (null == entity.getId()) {
			return getTimeLimitProdDao().save(entity);
		}
		return getTimeLimitProdDao().update(entity);
	}

	/**
	 * 新增限购商品
	 */
	@Override
	@Transactional(readOnly = false)
	public void addTimeLimitProd(Product product, Shelf shelf) {
		TimeLimitProd tlp;
		CommonCriteria criteria = new CommonCriteria();
		criteria.addEq("shelfId", shelf.getShelfId());
		criteria.addEq("productId", product.getProductId());
		List<TimeLimitProd> tlpList = getTimeLimitProdDao().getList(criteria, null);
		if (null == tlpList || tlpList.isEmpty()) {
			if ("N".equals(shelf.getIsLimitBuy())) {
				return;
			}
			TimeLimitMain tlm;
			criteria = new CommonCriteria();
			criteria.addEq("categoryID", -1);
			if (getListSize(criteria).intValue() > 0) {
				tlm = getList(0, -1, criteria, new String[] { "createDate desc" }).get(0);
			} else {
				tlm = new TimeLimitMain();
				tlm.setCategoryID(-1);
				tlm.setSaleDate(new Date());
				tlm.setName("一元秒杀");
				tlm = save(tlm);
			}
			tlp = new TimeLimitProd();
			tlp.setMainId(tlm.getId());
		} else {
			tlp = tlpList.get(0);
			if ("N".equals(shelf.getIsLimitBuy())) {
				getTimeLimitProdDao().delete(tlp);
				return;
			}
		}
		tlp.setShelfId(shelf.getShelfId());
		tlp.setStartDate(shelf.getStartDate());
		tlp.setEndDate(shelf.getEndDate());
		tlp.setImagePath("");

		tlp.setProductId(product.getProductId());
		tlp.setLimitPrice(shelf.getShelfPrice());
		tlp.setMemberPrice(null == product.getPrpsShelfPrice() ? new BigDecimal(0) : product.getPrpsShelfPrice());
		tlp.setProductName(StringUtils.substring(product.getProductName(), 0, 40));
		tlp.setIdxProductName("一元秒杀商品");
		tlp.setImagePath("img_path");
		tlp.setIsLimitBuy("Y");
		tlp.setIsRepeat("N");
		tlp = saveOrUpdateTimeLimitProd(tlp);

		try {
			DateFormat df2 = new SimpleDateFormat("yyyyMMddHHmmss");
			updateData(df2.format(new Date()));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 新增团购限购商品
	 */
	@Override
	@Transactional(readOnly=false)
	public void addTuangouTimeLimitProd(Product product,ShelfTuangou shelfTuangou){
		TimeLimitProd tlp;
		CommonCriteria criteria=new CommonCriteria();
		criteria.addEq("tuangouId",shelfTuangou.getTuangouId());
		criteria.addEq("productId",product.getProductId());
		List<TimeLimitProd> tlpList=getTimeLimitProdDao().getList(criteria,null);
		
		if(null==tlpList || tlpList.isEmpty()){
			if("N".equals(shelfTuangou.getMemberLimit())) return;
			
			TimeLimitMain tlm;
			criteria=new CommonCriteria();
			criteria.addEq("categoryID",-2);
			if(getListSize(criteria).intValue() > 0){
				tlm=getList(0,-1,criteria,new String[]{"createDate desc"}).get(0);
			}else{
				tlm=new TimeLimitMain();
				tlm.setCategoryID(-2);
				tlm.setSaleDate(new Date());
				tlm.setName("团购活动限购商品");
				tlm=save(tlm);
			}
			
			tlp=new TimeLimitProd();
			tlp.setMainId(tlm.getId());
		}else{
			tlp=tlpList.get(0);
			if("N".equals(shelfTuangou.getMemberLimit())){
				getTimeLimitProdDao().delete(tlp);
				return;
			}
		}
		
		tlp.setTuangouId(shelfTuangou.getTuangouId());
		tlp.setStartDate(shelfTuangou.getStartDate());
		tlp.setEndDate(shelfTuangou.getEndDate());
		tlp.setProductId(product.getProductId());
		tlp.setLimitPrice(shelfTuangou.getPrice());
		tlp.setMemberPrice(null==product.getPrpsShelfPrice() ? new BigDecimal(0) : product.getPrpsShelfPrice());
		tlp.setProductName(StringUtils.substring(product.getProductName(),0,40));
		tlp.setIdxProductName("团购活动限购商品");
		tlp.setImagePath("img_path");
		tlp.setIsLimitBuy("Y");
		tlp.setIsRepeat("N");
		tlp=saveOrUpdateTimeLimitProd(tlp);
		
		try{
			DateFormat df2=new SimpleDateFormat("yyyyMMddHHmmss");
			updateData(df2.format(new Date()));
		}catch (Exception e){
			e.printStackTrace();
		}
	}

	public ObjectDao<TimeLimitNow> getTimeLimitNowDao() {
		return timeLimitNowDao;
	}

	public void setTimeLimitNowDao(ObjectDao<TimeLimitNow> timeLimitNowDao) {
		this.timeLimitNowDao = timeLimitNowDao;
	}

	public ObjectDao<TimeLimitProd> getTimeLimitProdDao() {
		return timeLimitProdDao;
	}

	public void setTimeLimitProdDao(ObjectDao<TimeLimitProd> timeLimitProdDao) {
		this.timeLimitProdDao = timeLimitProdDao;
	}

	public ObjectDao<EventImage> getEventImageDao() {
		return eventImageDao;
	}

	public void setEventImageDao(ObjectDao<EventImage> eventImageDao) {
		this.eventImageDao = eventImageDao;
	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	/**
	 * 分線維護權限檢核
	 * 
	 * @param commcriteria
	 * @return
	 */
	CriteriaInRlike mergeCritInRlike(CommonCriteria commcriteria, String tableParam) {
		CriteriaInRlike critInRlike = null;
		User user = AdminHelper.getUser();
		if (null != user) {
			if (null == commcriteria) {
				commcriteria = new CommonCriteria();
			}
			critInRlike = new CriteriaInRlike(commcriteria);
			// 若 user 是 PM部門, 檢核 product.category 的 orgnizationPath 是否合乎規定
			if (user.getPermissions(Type.CATEGORY).size() > 0) {
				List<Serializable> prs = new ArrayList<Serializable>();
				for (UserPermission up : user.getPermissions(Type.CATEGORY).values()) {
					prs.add(up.getPermissionCode() + STRING_SYMBOL);
				}
				critInRlike.addInRlike(tableParam, prs);
			}
		} else {
			if (null == commcriteria) {
				commcriteria = new CommonCriteria();
			}
			critInRlike = new CriteriaInRlike(commcriteria);
		}
		return critInRlike;
	}
}